package com.samoiloff.ui.list.smart.interfaces {
	import flash.geom.Rectangle;
	import flash.events.MouseEvent;
	import flash.display.Sprite;
	import flash.events.EventDispatcher;

	/**
	 * @author Samoiloff
	 * 
	 * Abstract Factory
	 */
	public class CellRenderer extends EventDispatcher {
		
		protected var _mc		: Sprite;
		
		protected var _data		:*;
		protected var _index	:int;
		
		public function CellRenderer(data:* = null, index:int = 0) {
			_data	= data;
			_index	= index;
		}

		public function instantiate(data: *, index: int): CellRenderer {
			throw new Error("Abstract factory method. Should be overriden");
		}
		
		public function get mc(): Sprite {
			if (_visible) {
				return _mc;
			} else {
				throw new Error("Not rendered.");
			}
		}
		
		/*
		 * Layout
		 */
		
		public function calculateBounds(bounds : Rectangle) : Rectangle {
			return bounds;
		}
		
		public function set bounds(bounds : Rectangle) : void {
			_bounds = bounds;
		}
		
		public function get bounds() : Rectangle {
			return _bounds;
		}

		protected var _bounds:Rectangle;
		
		/*
		 * Render
		 */
		private var _visible	: Boolean; 
		
		public function get visible(): Boolean {
			return _visible;
		}
		
		public function set visible(visible: Boolean): void {
			if (visible != _visible) {
				_visible = visible;
				if (_visible) {
					render();
				} else {
					obscure();
				}
			}
		}
		
		protected function render(): void {
			_mc = new Sprite();
			_mc.mouseChildren = false;
			
			_mc.useHandCursor = _mc.buttonMode = true;
			if (_bounds) {
				_mc.x = _bounds.x;
				_mc.y = _bounds.y;
			}
			_mc.addEventListener(MouseEvent.CLICK, dispatchEvent);
		}

		protected function obscure(): void {
			_mc.removeEventListener(MouseEvent.CLICK, dispatchEvent);
			_mc = null;
		}
		
		public function get index(): int {
			return _index;
		}
		
		/*
		 * selected
		 */
		
		private var _selected: Boolean;
		
		public function get selected(): Boolean {
			return _selected;
		}
		
		public function set selected(selected: Boolean): void {
			_selected = selected;
		}

		/*
		 * Enabled
		 */
		
		private var _enabled: Boolean;
				
		public function get enabled(): Boolean {
			return _enabled;
		}
		
		public function set enabled(enabled: Boolean): void {
			_enabled = enabled;
		}
		
		public function get data(): * {
			return _data;
		}
	}
}
